//
//  VideoPlayerLayerType.swift
//  VideoPlayer
//
//  Created by JY_NEW on 2021/10/8.
//

import Foundation
import UIKit

// MARK: 浮层类型

/// 浮层种类
public enum VideoPlayerLayerCategory {
    /// 播放器插件层(插件层就算level一样也会一起显示，显示层级按加入顺序，后加入的在上面)
    case plugin
    /// 播放器状态层
    case state
    /// 播放器控制层
    case control
    /// 播放器遮挡层(遮挡层显示时会关闭所有控制层)[有遮挡层时自动暂停，这个通过autoPauseFlag实现，不特定在该层了]
    case block
    /// 其他用户自定义层，没有特定操作，暂时跟状态层除了默认层级高点，没有不一样
    case other
}

// MARK: 浮层等级

/// 浮层显示等级，高等级会显示在低等级上面，除插件外，同等级的同一时间只会显示最后加入layerManager的那个(关闭后会自动显示前一个加入顺序最近且激活的)
public enum VideoPlayerLayerLevel: Equatable {
    public typealias RawValue = Int
    public init?(rawValue: Int) {
        self = .value(rawValue)
    }
    public var rawValue: Int {
        switch self {
            case let .value(v) : return v
        }
    }
    
    case value(Int)
    /// 显示层级低
    public static var low: Self { return .value(250) }
    /// 插件层在普通层之下
    public static var plugin: Self { return .value(350) }
    /// 状态层在普通层之下插件层之上
    public static var state: Self { return .value(450) }
    /// 一般显示层级
    public static var normal: Self { return .value(500) }
    /// 控制层在普通层之上
    public static var control: Self { return .value(625) }
    /// 显示层级高
    public static var high: Self { return .value(750) }
    /// 遮挡层在所有层之上
    public static var block: Self { return .value(1001) }
    /// 比当前优先级高一点
    public var higher: Self { return self.higher(1) }
    /// 比当前优先级低一点
    public var lower: Self { return self.lower(1) }
    /// 比当前优先级高一点
    public func higher(_ value: Int) -> Self {
        return .value(self.rawValue + value)
    }
    /// 比当前优先级低一点
    public func lower(_ value: Int) -> Self {
        return .value(self.rawValue - value)
    }
}

// MARK: 浮层动画方向

/// 浮层动画方向
public enum VideoPlayerLayerAnimationDirection {
    case top
    case left
    case bottom
    case right
    case center
}

// MARK: 浮层状态

/// 浮层当前激活状态
public enum VideoPlayerLayerActivationStatus: Equatable {
    /// 激活(是否隐藏显示)
    case actived(hide:Bool)
    /// 未激活
    case deactived
    /// 是否激活
    public var isActived: Bool {
        switch self {
        case .deactived: return false
        default: return true
        }
    }
    /// 是否隐藏（包括激活但不显示和非激活状态）
    public var isHidden: Bool {
        switch self {
        case let .actived(hide: hide): return hide
        default: return true
        }
    }
    /// 是否显示
    public var isShowed: Bool {
        return !self.isHidden
    }
    /// 是否激活并且隐藏
    public var isActivedAndHidden: Bool {
        switch self {
        case let .actived(hide: hide): return hide
        default: return false
        }
    }
}

// MARK: 播放器浮层

/// 播放器浮层
public protocol VideoPlayerLayerType: AnyObject {
    /// 标识，则管理器配置
    var identifier: Int? { get set }
    /// 实现时需使用weak，用于控制播放器
    var playerManager: VideoPlayerManagerType? { get set }
    /// 实现时需使用weak，用于配合管理器
    var manager: VideoPlayerLayerManagerType? { get set }
    /// 浮层种类，不同种类会有不一样的行为
    var category: VideoPlayerLayerCategory { get }
    /// 显示层级
    var level: VideoPlayerLayerLevel { get }
    /// 当前显示状态，由manager去管理，外部或自身都不要设置该值
    var status: VideoPlayerLayerActivationStatus { get set }
    /// 是否禁用，若禁用则调用active和deactive都不会生效
    var isDisabled: Bool { get set }
    /// 自动暂停标记，若该标记有值则每次激活时会使用该标记暂停，并在反激活时使用该标记播放，注意该值不能变动必须是个固定值，默认无值
    var autoPauseFlag: Int? { get }
    /// 点击空白处自动取消激活，控制层默认true，其他默认false
    var isDeactiveForTapBlank: Bool { get }
    /// 浮层的全部页面放到该视图下，在didSet时做初始化，只会赋值一次
    var containerView: UIView? { get set }
    /// 父视图尺寸发生变化时会触发该方法，包括第一次设置containerView
    /// 取消，使用自动布局即可，若需手动布局(不建议使用)则自己进行相关事件的注册，
    //    func layoutSubviews()
    /// 显示，激活时会将superview显示到播放器，可执行动画，执行完成后调用completion
    func show(completion:@escaping () -> Void)
    /// 隐藏，关闭后会将superview从播放器移除(调用completion后)，可执行动画，执行完成后调用completion
    func hide(completion:@escaping () -> Void)
    /// 自身被激活
    func willActive()
    /// 自身被取消激活
    func willDeactive()
    /// 自身被激活
    func didActived()
    /// 自身被取消激活
    func didDeactived()
}

extension VideoPlayerLayerType {
    public var level: VideoPlayerLayerLevel {
        switch self.category {
        case .plugin: return .plugin
        case .state: return .state
        case .control: return .control
        case .block: return .block
        case .other: return .normal
        }
    }
    public var autoPauseFlag: Int? {
        return nil
    }
    /// 点击空白处自动取消激活
    public var isDeactiveForTapBlank: Bool {
        switch self.category {
        case .control: return true
        default: return false
        }
    }
}

// MARK: 辅助操作

extension VideoPlayerLayerType {
    /// 激活动画
    public func aniamteShow(for view: UIView, from direction: VideoPlayerLayerAnimationDirection, duration: TimeInterval = 0.25, completion:(() -> Void)? = nil) {
        view.layoutIfNeeded()
        switch direction {
        case .top:
            view.transform = .init(translationX: 0, y: -view.bounds.size.height - view.frame.origin.y)
        case .left:
            view.transform = .init(translationX: -view.bounds.size.width - view.frame.origin.x, y: 0)
        case .bottom:
            let totalHeight = view.superview?.bounds.size.height ?? (view.bounds.size.height + view.frame.origin.y)
            view.transform = .init(translationX: 0, y: totalHeight - view.frame.origin.y)
        case .right:
            let totalWidth = view.superview?.bounds.size.width ?? (view.bounds.size.width + view.frame.origin.x)
            view.transform = .init(translationX: totalWidth - view.frame.origin.x, y: 0)
        case .center:
            view.transform = .init(scaleX: 0.25, y: 0.25)
        }
        UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut) {
            view.transform = .identity
        } completion: { finished in
            if finished {
                completion?()
            }
        }
    }
    /// 关闭动画
    public func aniamteHide(for view: UIView, to direction: VideoPlayerLayerAnimationDirection, duration: TimeInterval = 0.25, completion:(() -> Void)? = nil) {
        UIView.animate(withDuration: duration, delay: 0, options: .curveEaseIn) {
            switch direction {
            case .top:
                view.transform = .init(translationX: 0, y: -view.bounds.size.height - view.frame.origin.y)
            case .left:
                view.transform = .init(translationX: -view.bounds.size.width - view.frame.origin.x, y: 0)
            case .bottom:
                let totalHeight = view.superview?.bounds.size.height ?? (view.bounds.size.height + view.frame.origin.y)
                view.transform = .init(translationX: 0, y: totalHeight - view.frame.origin.y)
            case .right:
                let totalWidth = view.superview?.bounds.size.width ?? (view.bounds.size.width + view.frame.origin.x)
                view.transform = .init(translationX: totalWidth - view.frame.origin.x, y: 0)
            case .center:
                view.transform = .init(scaleX: 0.25, y: 0.25)
            }
        } completion: { finished in
            if finished {
                view.transform = .identity
                completion?()
            }
        }
    }
    /// 激活动画
    public func aniamteShow(for view: UIView, duration: TimeInterval = 0.25, completion:(() -> Void)? = nil) {
        view.alpha = 0
        UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut) {
            view.alpha = 1
        } completion: { [weak self] finished in
            // 如果打开的过程中又关闭了，则不执行后续操作
            if self?.status.isShowed ?? true {
                completion?()
            }        
        }
    }
    /// 关闭动画
    public func aniamteHide(for view: UIView, duration: TimeInterval = 0.25, completion:(() -> Void)? = nil) {
        UIView.animate(withDuration: duration, delay: 0, options: .curveEaseIn) {
            view.alpha = 0
        } completion: { [weak self] finished in
            // 如果关闭的过程中又打开了，则不执行后续操作
            if self?.status.isHidden ?? true {
                completion?()
                view.alpha = 1
            }
        }
    }
}
